﻿using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Text.Encodings.Web;
using System.Threading.Tasks;

//https://stackoverflow.com/questions/38247080/using-razor-outside-of-mvc-in-net-core
namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {
            var configBuilder = new ConfigurationBuilder();
            configBuilder.AddInMemoryCollection(new Dictionary<string, string>() {
                { "name","zhangsan"},
                { "age","18"}
            });
            var config = configBuilder.Build();

            var host = new WebHostBuilder()
                .UseKestrel()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseConfiguration(config)
                .UseStartup<Startup>()
                //.ConfigureServices(services => services.AddRouting())
                //.Configure(app => app.UseRouter(routes =>
                //{
                //    routes.DefaultHandler = new RouteHandler((httpContext) =>
                //    {
                //        var request = httpContext.Request;
                //        return httpContext.Response.WriteAsync($"Verb =  {request.Method.ToUpperInvariant()} - Path = {request.Path} - Route values - {string.Join(", ", httpContext.GetRouteData().Values)}");
                //    });

                //    routes.MapGet("api/get/{id}", (request, response, routeData) => response.WriteAsync($"API Get {routeData.Values["id"]}"))
                //          .MapMiddlewareRoute("api/middleware", (appBuilder) => appBuilder.Use((httpContext, next) => httpContext.Response.WriteAsync("Middleware!")))
                //          .MapRoute(
                //            name: "AllVerbs",
                //            template: "api/all/{name}/{lastName?}",
                //            defaults: new { lastName = "Doe" },
                //            constraints: new { lastName = new RegexRouteConstraint(new Regex("[a-zA-Z]{3}", RegexOptions.CultureInvariant, RegexMatchTimeout)) });
                //}))
                .Build();
            host.Run();
        }
    }

    class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            //启用路由
            services.AddRouting();
            //services.AddMvc();
            //services.AddSingleton<RazorViewRenderer>();
            //services.AddSession();
            //services.AddLogging(builder =>
            //{
            //    builder.AddFilter("Demo.Startup", LogLevel.Information);
            //    builder.AddConsole();
            //});
            services.AddLocalization(options =>
            {
                options.ResourcesPath = "myresources";
            });
        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            #region 合并

            //配置路由
            //app.UseRouter(routes =>
            //{
            //    //根路径 /
            //    routes.MapGet("", context =>
            //    {
            //        return context.Response.WriteAsync("This is Root Path Page");
            //    });

            //    routes.MapGet("hello", context =>
            //    {
            //        return context.Response.WriteAsync("Got a Get request at /hello");
            //    });

            //    routes.MapPost("hello", context =>
            //    {
            //        return context.Response.WriteAsync("Got a Post request at /hello");
            //    });

            //    routes.MapDelete("hello", context =>
            //    {
            //        return context.Response.WriteAsync("Got a Delete request at /hello");
            //    });

            //    routes.MapPut("hello", context =>
            //    {
            //        return context.Response.WriteAsync("Got a Put request at /hello");
            //    });
            //});

            //使用静态资源
            //app.UseStaticFiles ();

            // app.UseStaticFiles (new StaticFileOptions {
            //     FileProvider = new PhysicalFileProvider (
            //             Path.Combine (Directory.GetCurrentDirectory (), "myfiles")),
            //         RequestPath = "/myfiles"
            // });


            ////模板渲染
            //app.UseRouter(routes =>
            //{
            //    //根路径 /
            //    routes.MapGet("", context =>
            //    {
            //        return context.Render("/views/index.cshtml");
            //    });

            //    routes.MapGet("/user", context =>
            //    {
            //        return context.Render("/views/user.cshtml", new UserInfo() { Name = "张三", Age = 18 });
            //    });
            //});

            ////请求数据
            //app.UseRouter(routes =>
            //{
            //    //根路径 /
            //    routes.MapGet("", context =>
            //    {
            //        var request = context.Request;

            //        var queryCollection = context.Request.Query;
            //        Console.WriteLine("-----------------------------------QueryString---------------------------------------------");
            //        foreach (var item in queryCollection)
            //        {
            //            Console.WriteLine(item.Key + ":" + item.Value);
            //        }


            //        if (HasApplicationFormContentType(context.Request.ContentType))
            //        {
            //            var formCollection = context.Request.Form;
            //            Console.WriteLine("-----------------------------------Form---------------------------------------------");
            //            foreach (var item in formCollection)
            //            {
            //                Console.WriteLine(item.Key + ":" + item.Value);
            //            }
            //        }



            //        if (HasMultipartFormContentType(context.Request.ContentType))
            //        {
            //            var formCollection = context.Request.Form;
            //            Console.WriteLine("-----------------------------------Multipart Form---------------------------------------------");
            //            foreach (var item in formCollection)
            //            {
            //                Console.WriteLine(item.Key + ":" + item.Value);
            //            }

            //            var fileCollections = context.Request.Form.Files;
            //            var rootPath = context.RequestServices.GetService<IHostingEnvironment>().ContentRootPath;
            //            foreach (var item in fileCollections)
            //            {

            //                var path = Path.Combine(rootPath, item.FileName);

            //                using (var stream = new FileStream(path, FileMode.Create))
            //                {
            //                    item.CopyToAsync(stream);
            //                }
            //                Console.WriteLine(item.FileName + ":" + item.Length);
            //            }
            //        }

            //        var headerCollection = context.Request.Headers;
            //        Console.WriteLine("-----------------------------------Header---------------------------------------------");
            //        foreach (var item in headerCollection)
            //        {
            //            Console.WriteLine(item.Key + ":" + item.Value);
            //        }

            //        StreamReader reader = new StreamReader(context.Request.Body);
            //        string text = reader.ReadToEnd();
            //        Console.WriteLine("-----------------------------------Body---------------------------------------------");
            //        Console.WriteLine(text);

            //        Console.WriteLine("-----------------------------------Cookies---------------------------------------------");
            //        var cookieCollection = context.Request.Cookies;
            //        foreach (var item in cookieCollection)
            //        {
            //            Console.WriteLine(item.Key + ":" + item.Value);
            //        }

            //        return context.Render("/views/index.cshtml");
            //    });
            //});

            //env.EnvironmentName = EnvironmentName.Development;
            //if (env.IsDevelopment())
            //{
            //    app.UseDeveloperExceptionPage();
            //}
            //else
            //{
            //    app.UseExceptionHandler("/error");
            //}

            //app.UseStatusCodePages();


            //app.UseStatusCodePagesWithRedirects("/status/{0}");

            //app.UseRouter(routes =>
            //{
            //    //""
            //    routes.MapGet("", context =>
            //    {
            //        return context.Response.WriteAsync("root path");
            //    });

            //    routes.MapGet("error", context =>
            //    {
            //        context.Response.StatusCode = 500;
            //        context.Response.ContentType = "text/html";
            //        var error = context.Features.Get<IExceptionHandlerFeature>();
            //        if (error != null)
            //        {
            //            return context.Response.WriteAsync("<h1>" + HtmlEncoder.Default.Encode("发生了错误: " + error.Error.Message) + "</h1>");
            //        }
            //        else
            //        {
            //            return context.Response.WriteAsync("<h1>" + HtmlEncoder.Default.Encode("Oops! 发生了错误,请联系管理员") + "</h1>");
            //        }
            //    });

            //    routes.MapGet("status/{code}", (request, response, routeData) =>
            //    {
            //        var statusCodePagesFeature = request.HttpContext.Features.Get<IStatusCodePagesFeature>();
            //        var code = routeData.Values["code"];
            //        if (statusCodePagesFeature != null && code!=null && code.ToString() == "404")
            //        {

            //            return request.HttpContext.Render("/views/404.cshtml");
            //        }
            //        else
            //        {
            //            return response.WriteAsync(HtmlEncoder.Default.Encode("状态码:"+ routeData.Values["code"]));
            //        }
            //    });

            //    //hello
            //    routes.MapGet("test", context =>
            //    {
            //        throw new Exception("空指针异常!!!");
            //    });
            //});

            //app.UseDeveloperExceptionPage();

            //app.UseSession();

            //app.UseRouter(routes =>
            //{
            //    routes.MapGet("", (request, response, routeData) =>
            //    {
            //        return request.HttpContext.Render("/views/login.cshtml");
            //    });

            //    routes.MapGet("home", context =>
            //    {
            //        string userName = context.Session.GetString("userName");
            //        if (!string.IsNullOrEmpty(userName))
            //        {
            //            return context.Response.WriteAsync("User:" + userName);
            //        }
            //        else
            //        {
            //            context.Response.Redirect("/");
            //            return Task.CompletedTask;
            //        }
            //    });

            //    routes.MapPost("login", context =>
            //    {
            //        var userName = context.Request.Form["UserName"].ToString();
            //        var password = context.Request.Form["PassWord"].ToString();
            //        if (userName.Equals("admin") && password.Equals("123456"))
            //        {
            //            context.Session.SetString("userName", password);
            //            context.Response.Redirect("/home");
            //            return Task.CompletedTask;
            //        }
            //        else
            //        {
            //            throw new Exception("用户名或密码错误");
            //        }
            //    });
            //});

            // app.UseRouter(routes =>
            // {
            //     routes.MapGet("", context =>
            //     {
            //         var config = context.RequestServices.GetService<IConfiguration>();
            //         string name = config["name"];
            //         string age = config["age"];
            //         //var logger = context.RequestServices.GetService<ILogger<Startup>>();
            //         //logger.LogInformation("before hello world");

            //         return context.Response.WriteAsync("name:"+name+",Age:"+age);
            //     });
            // });
            #endregion


            var cultureList = new List<CultureInfo>() {
                     new CultureInfo("en-US"),
                     new CultureInfo("zh-CN")
            };
            var options = new RequestLocalizationOptions()
            {
                SupportedCultures = cultureList,
                SupportedUICultures = cultureList,
                DefaultRequestCulture = new RequestCulture("zh-CN")
            };
            var provider = new QueryStringRequestCultureProvider();
            provider.QueryStringKey = "culture";
            provider.UIQueryStringKey = "uiculture";
            options.RequestCultureProviders.Clear();
            options.RequestCultureProviders.Add(provider);

            app.UseRequestLocalization(options);

            app.UseRouter(routes =>
            {
                routes.MapGet("", context =>
                {
                    //var stringLocalizerFactory = context.RequestServices.GetService<IStringLocalizerFactory>();
                    //var assemblyName = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
                    //var stringLocalizer = stringLocalizerFactory.Create("Startup", assemblyName);

                    var stringLocalizer = context.RequestServices.GetService<IStringLocalizer<Startup>>();
                    var requestCultureFeature = context.Features.Get<IRequestCultureFeature>();
                    var requestCulture = requestCultureFeature.RequestCulture;

                    string sayhi = stringLocalizer["sayhi"];
                    context.Response.ContentType = "text/html;charset=utf-8;";
                    //var localizer = context.RequestServices.GetService<IStringLocalizer<Startup>>();
                    return context.Response.WriteAsync(sayhi);
                });
            });
        }

        private bool HasApplicationFormContentType(string contentType)
        {
            return contentType != null && contentType.ToLower().Contains("application/x-www-form-urlencoded");
        }

        private bool HasMultipartFormContentType(string contentType)
        {
            return contentType != null && contentType.ToLower().Contains("multipart/form-data");
        }

    }

    public class UserInfo
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
}